﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using zserialize;
using XLua;
using Game;

public class LuaMonoBehaviour : MonoBehaviour
{
    //static LuaFunction getClassFun;
    static LuaEnv luaState;

    private LuaTable _luaObj;
    private String _luaCtrlName;
    private object dataObj;

    public LuaTable GetLuaObj()
    {
        return _luaObj;
    }
   
    public void SetLuaCtrlName(string luaCtrlName)
    {
        _luaCtrlName = luaCtrlName;
    }

    public void SetDataObj(object dataObj)
    {
        this.dataObj = dataObj;
    }

    
    void CreateLuaObj()
    {
        if (luaState == null)
        {
            luaState = LuaEnvMgr.GetLuaEnv();
        }
        if (luaState == null) return;

        if (_luaObj != null) return;

        object dataObj = this.dataObj != null ? this.dataObj : this;
        var winData = this.GetComponent<LuaDataBehaviour>();
        if (winData != null)
        {
            if (string.IsNullOrEmpty(_luaCtrlName))
            {
                _luaCtrlName = winData.GetType().Name;
            }

            var fun3 = luaState.Global.Get<System.Func<System.Object, System.Object>>("CreateDataContainerProxy");
            dataObj = fun3(winData);
        }
        else
        {
            SerializableFieldContainerBehaviour fieldContainer = this.GetComponent<SerializableFieldContainerBehaviour>();
            if (fieldContainer != null)
            {
                _luaCtrlName = fieldContainer.GetFieldDictionary().className;

                var fun2 = luaState.Global.Get<System.Func<System.Object, System.Object>>("CreateDataContainerProxy");
                dataObj = fun2(fieldContainer);
            }
        }

        try
        {
            luaState.DoString($"require('{_luaCtrlName}')");
        }
        catch (System.Exception e)
        {
            Debug.LogError(e.Message);
            return;
        }

        string realLuaCtrlName = System.IO.Path.GetFileName(_luaCtrlName);
        var fun = luaState.Global.Get<System.Func<System.Object, System.Object, System.Object, System.Object>>("CreateBehaviourProxy");
        _luaObj = fun(realLuaCtrlName, dataObj, this) as LuaTable;
    }

 //   public virtual void Init(LuaTable _luaParam = null)
	//{
 //       CreateLuaObj();


 //       Call("Init", _luaParam);
 //       if (this.enabled)
 //       {
 //           OnEnable();
 //       }

 //   }

    protected virtual void Awake()
    {
        CreateLuaObj();

        Call("Awake");
    }

	protected virtual void Start()
	{
        Call("Start");
	}

	protected virtual void OnEnable()
	{
        Call("OnEnable");
	}

	protected virtual void OnDisable()
	{
        Call("OnDisable");
	}

	protected virtual void OnDestroy()
	{
        Call("OnDestroy");
        if (_luaObj != null && luaState != null)
        {
            _luaObj.Dispose ();
            _luaObj = null;
		}

        dataObj = null;
	}

    protected virtual void Call(string methodName, params object[] param)
    {
        if (_luaObj == null || _luaCtrlName == null || luaState == null)
        {
            return;
        }

        var getClassFun = luaState.Global.Get<System.Func<System.Object, System.Object, LuaFunction>>("GetClassFun");
        var func = getClassFun(_luaObj, methodName);
        func?.Call(_luaObj, param);
    }
}
